package com.system.core.utils;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Iterator;

import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;

import org.apache.commons.codec.binary.Hex;
import org.apache.commons.io.IOUtils;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class ImageSize {

	private static String DEFAULT_PREVFIX = "thumb_";
	private static Boolean DEFAULT_FORCE = false;// 建议该值为false

	public static String getFormat(byte[] filebytes) {
		try {
			return getFormat(new ByteArrayInputStream(filebytes));
		} catch (Exception e) {
			e.printStackTrace();
			return "unknown";
		}
	}

	public static String getFormat(InputStream is) {
		try {

			ImageInputStream iis = ImageIO.createImageInputStream(is);
			Iterator<ImageReader> iter = ImageIO.getImageReaders(iis);
			if (!iter.hasNext()) {
				throw new RuntimeException("No readers found!");
			}

			ImageReader reader = iter.next();
			iis.close();
			return reader.getFormatName();
		} catch (Exception e) {
			e.printStackTrace();
			return "unknown";
		} finally {
			try {
				is.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public static String getFormat(String file) {
		try {
			return getFormat(new FileInputStream(file));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 
	 * 是否横向图
	 * 
	 * @param img
	 * @return
	 * @Operation(summary = "isHorizontal")
	 */
	public static boolean isHorizontal(byte[] img) {
		
		try (ByteArrayInputStream bais = new ByteArrayInputStream(img)) {
			
			BufferedImage image = ImageIO.read(bais);
			int width = image.getWidth();
			int height = image.getHeight();
			if (width > height)
				return true;
			
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}
		return false;
		
	}

	public static boolean isJPEGByZhongJin(byte[] picData) {
		String[] jpegformat = new String[] { "FFD8FFE0", "FFD8FFE1", "FFD8FFE8" };
		byte[] dest = new byte[4];
		System.arraycopy(picData, 0, dest, 0, 4);
		String format = new String(Hex.encodeHex(dest)).toUpperCase();
		boolean isjpeg = false;
		for (String tmp : jpegformat) {
			if (tmp.equalsIgnoreCase(format)) {
				isjpeg = true;
			}
		}
		if (!isjpeg) {
			log.warn("[图片判断]判断图片类型为非JPEG，源文件类型是：{}", format);
		}
		return isjpeg;
	}

	public static void main(String[] args) throws Exception {
		ImageSize.thumbnailImage("C:\\Users\\jlcon\\Pictures\\Saved Pictures\\bfaf826b8c6f4fc812e17879462ab6b0.jpg",
				400, 400, ImageSize.DEFAULT_PREVFIX, ImageSize.DEFAULT_FORCE);
		System.out.println(ImageSize.getFormat("e:/1.jpg"));

		FileOutputStream fos = new FileOutputStream("e:/tmp.jpg");
		fos.write(parseToJPG(new FileInputStream("e:/1.jpg")));
		fos.flush();
		fos.close();
		System.out.println(ImageSize.getFormat("e:/tmp.jpg"));

		boolean isjpeg = ImageSize.isJPEGByZhongJin(IOUtils.toByteArray(new FileInputStream("e:/tmp.jpg")));
		System.out.println(isjpeg);

		System.out.println(ImageSize.isHorizontal(IOUtils.toByteArray(new FileInputStream("e:/tmp1.jpg"))));
	}

	public static byte[] parseToJPG(byte[] filebytes) {
		try {
			return parseToJPG(new ByteArrayInputStream(filebytes));
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	public static byte[] parseToJPG(InputStream is) {
		try {
			BufferedImage bufferedImage = ImageIO.read(is);

			BufferedImage newBufferedImage = new BufferedImage(bufferedImage.getWidth(), bufferedImage.getHeight(),
					BufferedImage.TYPE_INT_RGB);

			newBufferedImage.createGraphics().drawImage(bufferedImage, 0, 0, Color.WHITE, null);

			ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
			ImageIO.write(newBufferedImage, "JPEG", byteOut);

			return byteOut.toByteArray();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} finally {
			try {
				is.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public static void readImage(OutputStream outputStream, String prefix,String imageFile, int widthOutput, int heightOutput) {
		readImage(outputStream, prefix,imageFile, widthOutput, heightOutput, false, "PNG");
	}

	public static void readImage(OutputStream outputStream, String prefix,String imageFile, int widthOutput, int heightOutput,
			boolean force, String formatName) {
		BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
		BufferedImage image = null;
		try {
			image = ImageIO.read(new File(prefix+"/"+imageFile));
		} catch (IOException e) {
			e.printStackTrace();
		}
		if (!force) {
			int width = image.getWidth();
			int height = image.getHeight();
			if ((width * 1.0) / widthOutput < (height * 1.0) / heightOutput) {
				if (width > widthOutput) {
					heightOutput = Integer
							.parseInt(new java.text.DecimalFormat("0").format(height * widthOutput / (width * 1.0)));
				}
			} else {
				if (height > heightOutput) {
					widthOutput = Integer
							.parseInt(new java.text.DecimalFormat("0").format(width * heightOutput / (height * 1.0)));
				}
			}
		}
		BufferedImage bufferedImage = new BufferedImage(widthOutput, heightOutput, BufferedImage.TYPE_INT_RGB);
		Graphics graphics = bufferedImage.getGraphics();
		graphics.drawImage(image, 0, 0, widthOutput, heightOutput, Color.LIGHT_GRAY, null);
		graphics.dispose();

//		Graphics2D graphics2D = bufferedImage.createGraphics();
//		graphics2D.setComposite(AlphaComposite.Src);
//		graphics2D.drawImage(image, 0, 0, widthOutput, heightOutput, null);

		try {
			ImageIO.write(bufferedImage, formatName, bufferedOutputStream);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * <p>
	 * 缩略图生成工具<br>
	 * 支持的图片类型 : [BMP, bmp, jpg, JPG, wbmp, jpeg, png, PNG, JPEG, WBMP, GIF,
	 * </p>
	 * <p>
	 * Description: 依据图片路径生成缩略图
	 * </p>
	 * 
	 * @param imagePath 原图片路径
	 * @param w         缩略图宽
	 * @param h         缩略图高
	 * @param prevfix   生成缩略图的前缀
	 * @param force     是否强制依照宽高生成缩略图(假设为false，则生成最佳比例缩略图)
	 */
	public static void thumbnailImage(String imagePath, int w, int h, String prevfix, boolean force) {
		File srcImgFile = new File(imagePath);
		if (srcImgFile.exists()) {
			try {
				String types = Arrays.toString(ImageIO.getReaderFormatNames());
				String suffix = null;
				// 获取图片后缀
				if (srcImgFile.getName().indexOf(".") > -1) {
					suffix = srcImgFile.getName().substring(srcImgFile.getName().lastIndexOf(".") + 1);
				} // 类型和图片后缀所有小写，然后推断后缀是否合法
				if (suffix == null || types.toLowerCase().indexOf(suffix.toLowerCase()) < 0) {
					System.out.println("Sorry, the image suffix is illegal. the standard image suffix is {}." + types);
					return;
				}
				BufferedImage image = ImageIO.read(srcImgFile);
				if (!force) {
					// 依据原图与要求的缩略图比例，找到最合适的缩略图比例
					int width = image.getWidth();
					int height = image.getHeight();
					if ((width * 1.0) / w < (height * 1.0) / h) {
						if (width > w) {
							h = Integer.parseInt(new java.text.DecimalFormat("0").format(height * w / (width * 1.0)));
						}
					} else {
						if (height > h) {
							w = Integer.parseInt(new java.text.DecimalFormat("0").format(width * h / (height * 1.0)));
						}
					}
				}
				BufferedImage bufferedImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
				Graphics graphics = bufferedImage.getGraphics();
				graphics.drawImage(image, 0, 0, w, h, Color.LIGHT_GRAY, null);
				graphics.dispose();
				String srcImgFilePath = srcImgFile.getPath();
				// 将图片保存在原文件夹并加上前缀
				ImageIO.write(bufferedImage, suffix,
						new File(srcImgFilePath.substring(0, srcImgFilePath.lastIndexOf(File.separator))
								+ File.separator + prevfix + srcImgFile.getName()));
				System.out.println("缩略图在原路径下生成成功");
			} catch (IOException e) {
				e.printStackTrace();
			}
		} else {
			System.out.println("the image is not exist.");
		}
	}
}
